﻿package com.cilico.single.components;

import java.util.Vector;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.cilico.single.ConfigManager;
import com.cilico.single.utils.Utils;
import com.cilico.single.view.BaseView;
import com.cilico.single.view.FormLayout;

/**
 * 保存html中的文字 如 <p>
 * @author lv.xiangan
 *
 */
public class mHtmlText extends TextView implements Component {
	private static int MAX_PARAGRAPH_WIDTH = Component.MAX_ROW_WIDTH - 10;
	private static int ADDW = 3;
	private Vector<HtmlText> textV_; // a list of HtmlText objects. Each one maybe
	/** A list of line breaks. */
	private final Vector<HtmlText> strings_;
	private int totalLink_;

	static final float Y_MARGIN = 1.3f;
	BaseView bv_;

	int width_;
	int height_;
	int left_; // Relative left position to the left of the FULL canvas.
	int top_; // Relative left position to the top of the FULL canvas.
	protected int clickedColor_;

	Paint font_;

	public CssStyle cssStyle_;
	public CssStyle pseudoStyle_;
	String linkAddr_;
	boolean isHyperLink_;
	protected boolean isClicked_ = false;
	boolean focus_;

	private boolean isTrimHeadBlank_;
	private boolean isBreakWord_;

	String isEncrypt_;

	// occupies more than one line, and NOT start at the
	// head of the line.

	static final class HtmlText {
		Paint f_;
		int c_; // the color
		int bc_ = android.graphics.Color.BLACK;
		boolean ul_; // underline
		int x_;
		String t_; // the text
		int linkId_ = -1;
		String linkTarget_;

		public HtmlText(String text, Paint font, int color, int bColor, boolean underline) {
			t_ = text;
			f_ = font;
			c_ = color;
			bc_ = bColor;
			ul_ = underline;
		}
	}

	public mHtmlText(Context context, String text, boolean isHyperLink, Paint f) {
		super(context);
		// TODO Auto-generated constructor stub
		bv_ = (BaseView) context;
		setText(text);
		this.setFocusableInTouchMode(true);

		font_ = f;
		font_.setTextSize(Utils.getScaledValue(ConfigManager.SIZE_IMGWAITLOAD));
		setFont(f);
		strings_ = new Vector<HtmlText>();
		totalLink_ = 0;

		LinearLayout.LayoutParams viewLayout = (LinearLayout.LayoutParams) getLayoutParams();
		if (null == viewLayout)
			viewLayout = new LinearLayout.LayoutParams(MAX_PARAGRAPH_WIDTH + ADDW, getStringLineHeight());
		setLayoutParams(viewLayout);

		width_ = viewLayout.width;
		height_ = viewLayout.height;
	}

	void setToLink(String linkTarget) {
		linkAddr_ = linkTarget;
	}

	void addText(String text, Paint font, int color, int bColor, boolean underline, boolean isLink, String linkTarget,
			boolean isTrimHeadBlank, boolean isBreakWord) {
		// 设置控件显示文字
		this.setText(text);

		if (textV_ == null)
			textV_ = new Vector<HtmlText>();
		HtmlText ht = new HtmlText(text, font, color, bColor, underline);
		if (isLink) {
			ht.linkId_ = totalLink_++;
			this.setFocusable(true);
		}
		ht.linkTarget_ = linkTarget;
		textV_.addElement(ht);
		isTrimHeadBlank_ = isTrimHeadBlank;
		isBreakWord_ = isBreakWord;
	}

	int getStringLineHeight() {
		return (int) (((font_ == null) ? 0 : font_.getTextSize()) * Y_MARGIN);
	}

	/**
	 * Break this text into lines, estimate total height based on number of lines and line break types. Don't do text
	 * abbreviation as done in ListItem.
	 */
	protected void estimateHeight(boolean isTrimHeadBlank, boolean isBreakWord) {
		if (strings_ == null)
			return;
		strings_.removeAllElements();
		height_ = 0;
		if (textV_ == null)
			return;

		int pos = 0;
		int endPos = 0;
		int[] lineBreak = new int[Utils.LBI_SIZE];
		int lineHeight = getStringLineHeight();
		int lineWidth = MAX_PARAGRAPH_WIDTH;
		int startX = 0;
		for (int idx = 0; idx < textV_.size(); idx++) {
			HtmlText ht = textV_.elementAt(idx);
			char[] chars = ht.t_.toCharArray();
			pos = 0;
			while (pos >= 0 && pos < chars.length) {
				endPos = Utils.getLineEndIndex(chars, pos, ht.f_, lineWidth + 10, lineBreak,
						lineWidth == MAX_PARAGRAPH_WIDTH, isTrimHeadBlank, isBreakWord);
				pos = lineBreak[Utils.LBI_START];
				if (endPos > pos) {
					HtmlText h = new HtmlText(new String(chars, pos, endPos - pos), ht.f_, ht.c_, ht.bc_, ht.ul_);
					h.linkId_ = ht.linkId_;
					h.linkTarget_ = ht.linkTarget_;
					if (startX != 0) {
						h.x_ = startX;
					} else {
						height_ += lineHeight;
					}
					strings_.addElement(h);
					if (endPos == chars.length) {
						lineWidth -= (ht.f_.measureText(h.t_) + ht.f_.measureText(" "));
						startX = 0;
					} else {
						lineWidth = MAX_PARAGRAPH_WIDTH;
						startX = 0;
					}
				} else if (endPos == pos) {
					lineWidth = MAX_PARAGRAPH_WIDTH;
					startX = 0;
				}
				if (lineWidth <= 0) {
					startX = 0;
					lineWidth = MAX_PARAGRAPH_WIDTH;
				}
				pos = endPos;
			}
		}
	}

	/**
	 * Sets the application's preferred font for rendering this Label. The font is a hint, and the implementation may
	 * disregard the application's preferred font. The font parameter must be a valid Font object or null. If the font
	 * parameter is null, the implementation must use its default font to render the Label.
	 * 
	 * @param font
	 *            the preferred font to use to render this Label
	 */
	protected void setFont(Paint font) {
		// TODO Auto-generated method stub
		if (font == null) {
			font = new Paint();
			font.setTypeface(Typeface.DEFAULT);
			font.setTextSize(Utils.getScaledValue(ConfigManager.SIZE_SMALL));
		}
		boolean isNeedReset = false;
		if (font_.getTypeface() != font.getTypeface() || font_.getStyle() != font.getStyle()
				|| font_.getTextSize() != font.getTextSize()) {
			isNeedReset = true;
		}
		font_ = font;
		if (isHyperLink_ && (!font_.isUnderlineText())) {
			font_.setUnderlineText(true);
		}
		if (isNeedReset) {
			setText(getText());
		}
	}

	public boolean onKeyDown(int keyCode, KeyEvent event) {
		switch (keyCode) {
		case KeyEvent.KEYCODE_DPAD_CENTER:

			break;
		default:
			return super.onKeyDown(keyCode, event);
		}
		return true;
	}

	public boolean onKeyUp(int keyCode, KeyEvent event) {
		switch (keyCode) {
		case KeyEvent.KEYCODE_DPAD_CENTER:
			isClicked_ = true;
			bv_.dealWithLink(this.linkAddr_, bv_, false);
			break;
		default:
			return super.onKeyDown(keyCode, event);
		}
		return true;
	}

	public boolean onTouchEvent(MotionEvent event) {
		int touchEvent = event.getAction();

		switch (touchEvent) {
		case MotionEvent.ACTION_DOWN:
			this.requestFocus();
			break;
		case MotionEvent.ACTION_UP:
			isClicked_ = true;
			bv_.dealWithLink(this.linkAddr_, bv_, false);
			break;
		default:
			return super.onTouchEvent(event);
		}
		return true;
	}

	protected void onDraw(Canvas g) {
		int xOrig = left_ + 2;
		int yOrig = top_;
		int sz = strings_.size();
		int maxHeight = getStringLineHeight() * sz;
		HtmlText ht = null;
		int dy = 0;
		int offset = -2;
		int preH = 0;
		int lineHeight = getStringLineHeight();
		for (int i = 0; i < sz && dy <= maxHeight; ++i) {
			ht = strings_.elementAt(i);
			// 设置字体非抗锯齿效果，使字体边界更平滑
			ht.f_.setAntiAlias(true);
			if (ht.x_ == 0) {
				dy += preH;
				preH = 0;
			}
			// draw background color
			ht.f_.setColor(ht.bc_);
			ht.f_.setStyle(Style.FILL);
//			g.drawRect(xOrig + ht.x_ - 1, yOrig + dy + 2, xOrig + ht.x_ + ht.f_.measureText(ht.t_) + 1, yOrig + dy
//					+ lineHeight + 2, ht.f_);
			if (focus_) {
				ht.f_.setColor(BaseView.HL_BACKGROUND_COLOR);
//				g.drawRect(xOrig + ht.x_, yOrig + dy, ht.f_.measureText(ht.t_), yOrig + dy + getLineHeight(), ht.f_);
			}
			if (isFocused()) {
				ht.f_.setColor(BaseView.HL_BACKGROUND_COLOR);
//				g.drawRect(xOrig + ht.x_, yOrig + dy, xOrig + ht.x_ + ht.f_.measureText(ht.t_), yOrig + dy
//						+ getLineHeight(), ht.f_);
				focus_ = false;
			}
			if (isClicked_ && clickedColor_ != 0) {
//				ht.f_.setColor(clickedColor_);
			} else {
				ht.f_.setColor(ht.c_);
			}
			if (ht.t_.length() > 0) {
				// android在绘制字符串时默认的锚点位置在字符串的左下角，且无法改变锚点的垂直位置，所以该处在绘制字符串时在Y方向上加入了一个行高的位置
				g.drawText(ht.t_, xOrig + ht.x_, yOrig + dy + offset + (int) (lineHeight + ht.f_.getTextSize()) / 2,
						ht.f_);
				if (ht.ul_)
					g.drawLine(xOrig + ht.x_, yOrig + dy + ht.f_.getTextSize() + offset + 5,
							xOrig + ht.x_ + ht.f_.measureText(ht.t_), yOrig + dy + ht.f_.getTextSize() + offset + 5,
							ht.f_);
				if (ht.x_ == 0)
					preH += lineHeight;
			}
		}
	}

	// 焦点改变时调用该方法
	protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
		if (gainFocus) {
			BaseView bv = (BaseView) this.getContext();
			bv.stopTicker();
		}
		super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
	}

	public void cleanText() {
		// TODO Auto-generated method stub

	}

	public String getContentText() {
		// TODO Auto-generated method stub
		return null;
	}

	public CssStyle getCssStyle() {
		// TODO Auto-generated method stub
		return null;
	}

	public int getCmpHeight() {
		// TODO Auto-generated method stub
		return height_;
	}

	public View getCmpView() {
		// TODO Auto-generated method stub
		return this;
	}

	public int getCmpWidth() {
		// TODO Auto-generated method stub
		return width_;
	}

	public boolean isInTable() {
		// TODO Auto-generated method stub
		return false;
	}

	public void mould() {
		CssStyle cs = cssStyle_;

		// set the text color.
		if (cs != null && cs.fgColor_ != 0) {
			setTextColor(cs.fgColor_);
		}
		// set the font family (since API Level 4)
		/*
		 * String fontPath = ConfigManager.getFontPath(cbStyle.fontFamily_); if (fontPath != null) {
		 * temp.setTypeface(Typeface.createFromFile(fontPath)); }
		 */
		// set the font size.
		if (cs != null && cs.fontSize_ > 0) {
			setTextSize(cs.fontSize_);
			font_.setTextSize(cs.fontSize_);
		}
		// set the background color.
		if (cs != null && cs.bgColor_ != 0) {
			setBackgroundColor(cs.bgColor_);
		}
		estimateHeight(isTrimHeadBlank_, isBreakWord_);

		LinearLayout.LayoutParams viewLayout = (LinearLayout.LayoutParams) getLayoutParams();
		if (null == viewLayout) {
			viewLayout = new LinearLayout.LayoutParams(MAX_PARAGRAPH_WIDTH + ADDW, height_);
		} else {
			viewLayout.height = height_;
		}
		// #ifdef Android1.0
//@		 viewLayout.topMargin = 2;
		// #endif
		setLayoutParams(viewLayout);
	}

	public void setContentText(String text) {
		// TODO Auto-generated method stub

	}

	public void setCssStyle(CssStyle style) {
		// TODO Auto-generated method stub

	}

	public void setInTable(boolean inTable) {
		// TODO Auto-generated method stub

	}

	public void setCmpHeidht(int height) {
		// TODO Auto-generated method stub

	}

	public void setCmpWidth(int width) {
		// TODO Auto-generated method stub

	}

	public void shrinkWidth() {
		// TODO Auto-generated method stub

	}

	public void releaseResource(View view) {
		// TODO Auto-generated method stub
		// textV_.removeAllElements();
		// textV_ = null;
		// font_ = null;
		// cssStyle_ = null;
		// pseudoStyle_ = null;
		// linkAddr_ = null;
	}

	public void setForm(FormLayout formLayout) {
		// TODO Auto-generated method stub

	}

	public FormLayout getForm() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setEncrypt(String encrypt) {
		// TODO Auto-generated method stub
		isEncrypt_ = encrypt;
	}
}
